package vip.xiaonuo.invoice.core.adapter.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.DigestUtil;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import vip.xiaonuo.invoice.core.adapter.dto.request.*;
import vip.xiaonuo.invoice.core.adapter.dto.result.*;
import vip.xiaonuo.invoice.core.enums.invoice.InvoiceErrorCodeEnum;
import vip.xiaonuo.invoice.core.exception.InvoiceException;
import vip.xiaonuo.invoice.core.listener.BizEventListener;
import vip.xiaonuo.invoice.core.util.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vip.xiaonuo.invoice.core.adapter.InvoicePlatformAdapter;

import java.util.*;

/**
 * 数族发票平台适配器
 *
 * @author AI Assistant
 */
@Component
@Slf4j
public class ShuZuInvoiceAdapter implements InvoicePlatformAdapter {

    /**
     * appid 、appSecret 请在数族开放平台上配置
     * 开放平台地址： http://dev.zhenpos.com/openPlat
     * 开放平台账号：请联系数族运营人员协助注册。
     */
//    //测试
//    private static final String URL = "https://paymgmt.dev.shuzutech.com";
//    private static final String APPID = "ae62a9d1b5acd39d06cd2b6a58894db0";
//    private static final String APPSECRET = "c5b3bdf9e8d184cb9eb835f308e7a479847ff94a";
//    private static final String path = "http://openplat.dev.shuzutech.com/openplat/dev/refreshAccessToken";//测试token

    // 生产
    private static final String URL = "https://paymgmt.shuzutech.com";
    private static final String APPID = "15d197b4d93ef8f1cf46fc2c86fd95f3"; //自己的appid
    private static final String APPSECRET = "3c876d401c875904dfe63c19e769344cfe177857"; //自己的appsecret
    private static final String path = "https://dev.zhenpos.com/openplat/dev/refreshAccessToken";

    private static final String ALLOWED_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    private static final int RANDOM_STRING_LENGTH = 8;
    private static final Random RANDOM = new Random();

    //-----------功能---------------
    @Override
    public InvoiceSubmitResultDto createInvoice(InvoiceRequestDto invoiceRequestDto) {
        InvoiceRequestDtoOfShuZu invoiceRequestDtoOfShuZu = (InvoiceRequestDtoOfShuZu) invoiceRequestDto;
        String sellerId = invoiceRequestDtoOfShuZu.getSellerId();
        // 从缓存中获取appId和appSecret
        Map<String, String> sellerInfo = BizEventListener.getSellerInfoById(sellerId);
        String dlzh = sellerInfo.get("loginAccount");
        String appId = sellerInfo.get("appId");
        String appSecret = sellerInfo.get("appSecret");

        try {
            // 构建数族发票请求参数
            String fpqqlsh = invoiceRequestDtoOfShuZu.getFpqqlsh();
            JSONObject body = buildInvoiceRequestBody(invoiceRequestDtoOfShuZu, fpqqlsh, dlzh);

            // 调用数族发票API
            System.out.println(body);
            String response = invoiceRequest(appId, appSecret, body.toString());
            log.info("数族发票API响应: {}", response);

            // 解析响应结果
            JSONObject jsonResponse = JSONUtil.parseObj(response);

            // 构建返回结果
            InvoiceSubmitResultDto result = new InvoiceSubmitResultDto();

            // 检查响应是否成功
            boolean success;
            int code;
            String description;

            if (jsonResponse.getStr("code").equals("0") || jsonResponse.getStr("code").equals("070004")) {
                success = true;
                description = "提交成功";
                code = InvoiceErrorCodeEnum.INVOICE_SUCCESS.getCode();
            } else {
                success = false;
                description = jsonResponse.getStr("msg");
                code = jsonResponse.getInt("code");
            }
//            if (jsonResponse.containsKey("msg")) {
//                description  = jsonResponse.getStr("msg");
//            }

            // 设置结果字段
            result.setSuccess(success);
            result.setCode(code);
            result.setDescription(description);
            return result;
        } catch (Exception e) {
            log.error("调用数族发票API异常: {}", e.getMessage(), e);
            InvoiceSubmitResultDto result = new InvoiceSubmitResultDto();
            result.setSuccess(false);
            result.setDescription("开具发票失败: " + e.getMessage());
            return result;
        }
    }

    @Override
    public RedeliverResultDto reDeliverInvoice(InvoiceRedeliverRequestDto redeliverRequestDto) {
        String sellerId = redeliverRequestDto.getSellerId();
        // 从缓存中获取appId和appSecret
        Map<String, String> sellerInfo = BizEventListener.getSellerInfoById(sellerId);
        String dlzh = sellerInfo.get("loginAccount");
        String appId = sellerInfo.get("appId");
        String appSecret = sellerInfo.get("appSecret");

        try {
            // 构建重新交付请求参数
            JSONObject body = buildRedeliverRequestBody(redeliverRequestDto, dlzh);

            // 调用数族发票重新交付API
            String response = redeliverRequest(appId, appSecret, body.toString());
            log.info("数族发票重新交付API响应: {}", response);

            // 解析响应结果
            JSONObject jsonResponse = JSONUtil.parseObj(response);
            RedeliverResultDto redeliverResultDto = new RedeliverResultDto();

            // 检查响应是否成功
            if (jsonResponse.getStr("code").equals("0")) {
                redeliverResultDto.setCode(0);
                redeliverResultDto.setSuccess(true);
                return redeliverResultDto;
            } else {
                log.error("重新交付发票失败: {}", jsonResponse.getStr("msg"));
                redeliverResultDto.setCode(Integer.parseInt(jsonResponse.getStr("code")));
                redeliverResultDto.setSuccess(false);
                redeliverResultDto.setDescription(jsonResponse.getStr("msg"));
                return redeliverResultDto;
            }
        } catch (Exception e) {
            log.error("重新交付发票异常: {}", e.getMessage(), e);
            RedeliverResultDto redeliverResultDto = new RedeliverResultDto();
            redeliverResultDto.setCode(InvoiceErrorCodeEnum.NONE_ERROR.getCode());
            redeliverResultDto.setSuccess(false);
            return redeliverResultDto;
        }
    }

    @Override
    public InvoiceResultDto queryInvoiceStatus(String sellerId, List<String> ids) {
        // 从缓存中获取appId和appSecret
        Map<String, String> sellerInfo = BizEventListener.getSellerInfoById(sellerId);
        String dlzh = sellerInfo.get("loginAccount");
        String appId = sellerInfo.get("appId");
        String appSecret = sellerInfo.get("appSecret");
        String nsrsbh = sellerInfo.get("sellerTaxNumber");
        String fpqqlsh = ids.get(0);
        try {
            // 构建数族发票查询请求参数
            JSONObject body = buildQueryInvoiceStatusBody(fpqqlsh, dlzh, nsrsbh);

            // 调用数族发票查询API
            String response = queryInvoiceRequest(appId, appSecret, body.toString());
            log.info("数族发票查询API响应: {}", response);

            // 解析响应结果
            JSONObject jsonResponse = JSONUtil.parseObj(response);
            System.out.println(jsonResponse);

            // 构建返回结果
            InvoiceResultDtoOfShuZU result = new InvoiceResultDtoOfShuZU();

            // 设置响应状态码和消息
            result.setCode(jsonResponse.getStr("code", "500"));
            result.setMsg(jsonResponse.getStr("msg", "未知返回结果"));

            // 处理成功情况，有content字段
            if (jsonResponse.containsKey("content") && !jsonResponse.isNull("content")) {
                JSONObject contentJson = jsonResponse.getJSONObject("content");
                InvoiceResultDtoOfShuZU.content content = new InvoiceResultDtoOfShuZU.content();

                // 设置发票基本信息
                content.setFphm(contentJson.getStr("fphm", ""));
                content.setZzfpdm(contentJson.getStr("zzfpdm", ""));
                content.setZzfphm(contentJson.getStr("zzfphm", ""));
                content.setGfsh(contentJson.getStr("gfsh", ""));
                content.setGfmc(contentJson.getStr("gfmc", ""));
                content.setXfsh(contentJson.getStr("xfsh", ""));
                content.setXfmc(contentJson.getStr("xfmc", ""));
                content.setFplxdm(contentJson.getStr("fplxdm", ""));

                // 设置文件URL
                content.setPdfUrl(contentJson.getStr("pdfUrl", ""));
                content.setOfdUrl(contentJson.getStr("ofdUrl", ""));
                content.setXmlUrl(contentJson.getStr("xmlUrl", ""));

                // 设置金额信息
                content.setKprq(contentJson.getStr("kprq", ""));
                content.setKpr(contentJson.getStr("kpr", ""));
                content.setHjje(contentJson.getStr("hjje", ""));
                content.setHjse(contentJson.getStr("hjse", ""));
                content.setJshj(contentJson.getStr("jshj", ""));
                content.setChzt(contentJson.getStr("chzt", ""));
                result.setContent(content);
            }

            return result;
        } catch (Exception e) {
            log.error("查询发票状态异常: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public RedInvoiceSubmitResultDto createRedInvoice(RedInvoiceRequestDto redInvoiceRequestDto) {

        RedInvoiceRequestDtoOfShuZu redInvoiceRequestDtoOfShuZu = (RedInvoiceRequestDtoOfShuZu) redInvoiceRequestDto;
        String sellerId = redInvoiceRequestDtoOfShuZu.getSellerId();

        // 从缓存中获取appId和appSecret
        Map<String, String> sellerInfo = BizEventListener.getSellerInfoById(sellerId);
        String dlzh = sellerInfo.get("loginAccount");
        String appId = sellerInfo.get("appId");
        String appSecret = sellerInfo.get("appSecret");
        try {
            // 构建数族红票请求参数
            JSONObject body = buildRedInvoiceRequestBody(redInvoiceRequestDtoOfShuZu, dlzh);

            // 调用数族红票API
            log.info("数族红票请求参数: {}", body);
            String response = redInvoiceRequest(appId, appSecret, body.toString());
            log.info("数族红票API响应: {}", response);

            // 解析响应结果
            JSONObject jsonResponse = JSONUtil.parseObj(response);

            // 构建返回结果
            RedInvoiceSubmitResultDto result = new RedInvoiceSubmitResultDto();

            // 检查响应是否成功
            boolean success = false;
            String code = "500";
            String description = "未知原因，冲红失败";
            String redInvoiceConfirmId = null;
            String redInvoiceConfirmNo = null;

            if (jsonResponse.containsKey("code") && jsonResponse.getStr("code").equals("0")) {
                success = true;
                description = jsonResponse.getStr("msg", "提交成功");
                code = "0";

                // 提取红票请求单确认id
                if (jsonResponse.containsKey("content") && !jsonResponse.isNull("content")) {
                    JSONObject content = jsonResponse.getJSONObject("content");
                    if (content.containsKey("hzfpxxqrdid")) {
                        redInvoiceConfirmId = content.getStr("hzfpxxqrdid");
                    }
                    if (content.containsKey("hzfpxxqrdbh")) {
                        redInvoiceConfirmNo = content.getStr("hzfpxxqrdbh");
                    }
                }
            } else if (jsonResponse.containsKey("msg")) {
                description = jsonResponse.getStr("msg");
            }

            // 设置返回结果字段
            result.setSuccess(success);
            result.setCode(Integer.parseInt(code));
            result.setDescription(description);
            result.setRedInvoiceConfirmId(redInvoiceConfirmId);
            result.setRedInvoiceConfirmNo(redInvoiceConfirmNo);

            return result;
        } catch (Exception e) {
            log.error("调用数族红票API异常: {}", e.getMessage(), e);
            RedInvoiceSubmitResultDto result = new RedInvoiceSubmitResultDto();
            result.setSuccess(false);
            result.setCode(500);
            result.setDescription("调用数族红票API异常: " + e.getMessage());
            return result;
        }
    }

    @Override
    public RedInvoiceResultDto queryRedInvoiceStatus(String sellerId, List<String> ids) {
        // 从缓存中获取appId和appSecret
        Map<String, String> sellerInfo = BizEventListener.getSellerInfoById(sellerId);
        String dlzh = sellerInfo.get("loginAccount");
        String appId = sellerInfo.get("appId");
        String appSecret = sellerInfo.get("appSecret");
        String nsrsbh = sellerInfo.get("sellerTaxNumber");
        String redInvoiceConfirmId = ids.get(0);

        try {
            // 构建数族红票查询请求参数
            JSONObject body = buildQueryRedInvoiceStatusBody(redInvoiceConfirmId, dlzh, nsrsbh);

            // 调用数族红票查询API
            String response = queryRedInvoiceStatusRequest(appId, appSecret, body.toString());
            log.info("数族红票查询API响应: {}", response);

            // 解析响应结果
            JSONObject jsonResponse = JSONUtil.parseObj(response);
            System.out.println(jsonResponse);

            // 构建返回结果（使用RedInvoiceResultDto类型）
            RedInvoiceResultDtoOfShuZu result = new RedInvoiceResultDtoOfShuZu();

            // 设置响应状态码和消息
            result.setCode(jsonResponse.getStr("code", "500"));
            result.setMsg(jsonResponse.getStr("msg", "未知返回结果"));

            // 处理成功情况，有content字段
            if (jsonResponse.containsKey("content") && !jsonResponse.isNull("content")) {
                JSONObject contentJson = jsonResponse.getJSONObject("content");
                RedInvoiceResultDtoOfShuZu.content content = new RedInvoiceResultDtoOfShuZu.content();

                // 基本信息
                content.setEwm(contentJson.getStr("ewm")); // 二维码
                content.setFphm(contentJson.getStr("fphm")); // 发票号码

                // 购销方信息
                content.setGfmc(contentJson.getStr("gfmc")); // 购方名称
                content.setGfsh(contentJson.getStr("gfsh")); // 购方税号
                content.setXfsh(contentJson.getStr("xfsh")); // 销方税号
                content.setXfmc(contentJson.getStr("xfmc")); // 销方名称

                // 发票类型和文件链接
                content.setFplxdm(contentJson.getStr("fplxdm")); // 发票类型代码
                content.setZzfpdm(contentJson.getStr("zzfpdm")); // 主管方发票代码
                content.setPdfUrl(contentJson.getStr("pdfUrl")); // PDF文件链接
                content.setOfdUrl(contentJson.getStr("ofdUrl")); // OFD文件链接
                content.setXmlUrl(contentJson.getStr("xmlUrl")); // XML文件链接

                // 日期和人员信息
                content.setKprq(contentJson.getStr("kprq")); // 开票日期
                content.setKpr(contentJson.getStr("kpr")); // 开票人

                // 金额信息
                content.setHjje(contentJson.getStr("hjje")); // 合计金额
                content.setHjse(contentJson.getStr("hjse")); // 合计税额
                content.setJshj(contentJson.getStr("jshj")); // 价税合计
                content.setFpzt(contentJson.getStr("fpzt")); // 发票状态

                // 商品明细列表
                if (contentJson.containsKey("mxList") && !contentJson.isNull("mxList")) {
                    String mxList = contentJson.getStr("mxList");
                    content.setMxList(mxList);
                }

                result.setContent(content);
            }

            return result;
        } catch (Exception e) {
            log.error("查询发票状态异常: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public GetValidSubmitResultDto getValidCode(String sellerId) {
        GetValidSubmitResultDto resultDto = new GetValidSubmitResultDto();
        try {
            // 从缓存中获取appId和appSecret
            Map<String, String> sellerInfo = BizEventListener.getSellerInfoById(sellerId);
            if (ObjectUtil.isEmpty(sellerInfo)) {
                throw new InvoiceException("未找到对应的销方信息");
            }

            String dlzh = sellerInfo.get("loginAccount");
            String appId = sellerInfo.get("appId");
            String appSecret = sellerInfo.get("appSecret");

            if (ObjectUtil.isEmpty(appId) || ObjectUtil.isEmpty(appSecret) || ObjectUtil.isEmpty(dlzh)) {
                throw new InvoiceException("商户配置信息不完整");
            }

            // 构建数族发票请求参数
            String serviceId = "DLYZ";
            JSONObject content = new JSONObject(); // content为空对象

            // 构建整体请求体
            JSONObject body = new JSONObject();
            body.put("serviceId", serviceId);
            body.put("dlzh", dlzh);
            body.put("nsrsbh", sellerInfo.get("sellerTaxNumber"));
            body.put("content", content);

            // 调用数族发票API
            log.info("获取验证码请求参数: {}", body);
            String response = getValidCodeRequest(appId, appSecret, body.toString());
            log.info("数族发票API响应: {}", response);

            // 解析响应结果
            JSONObject jsonResponse = JSONUtil.parseObj(response);
            String code = jsonResponse.getStr("code");
            String msg = jsonResponse.getStr("msg");

            // 检查响应是否成功
            if ("070003".equals(code)) {
                resultDto.setSuccess(true);
                resultDto.setCode(InvoiceErrorCodeEnum.GET_VALID_CODE_SUCCESS.getCode());
                resultDto.setDescription(msg);
                log.info("获取验证码成功，商户ID: {}", sellerId);
            } else {
                String message = jsonResponse.getStr("msg", "获取验证码失败");
                resultDto.setSuccess(false);
                resultDto.setDescription(message);
                log.error("获取验证码失败: {}", message);
                throw new InvoiceException(message);
            }
        } catch (Exception e) {
            resultDto.setSuccess(false);
            resultDto.setDescription("获取验证码失败，请稍后重试");
            log.error("获取验证码时发生异常", e);
            throw new InvoiceException("获取验证码失败，请稍后重试");
        }
        return resultDto;
    }

    @Override
    public CommitValidSubmitResultDto commitValidCode(String sellerId,String validCode) {
        CommitValidSubmitResultDto resultDto = new CommitValidSubmitResultDto();
        try {
            // 从缓存中获取appId和appSecret
            Map<String, String> sellerInfo = BizEventListener.getSellerInfoById(sellerId);
            if (ObjectUtil.isEmpty(sellerInfo)) {
                throw new InvoiceException("未找到对应的销方信息");
            }

            String dlzh = sellerInfo.get("loginAccount");
            String appId = sellerInfo.get("appId");
            String appSecret = sellerInfo.get("appSecret");

            if (ObjectUtil.isEmpty(appId) || ObjectUtil.isEmpty(appSecret) || ObjectUtil.isEmpty(dlzh)) {
                throw new InvoiceException("商户配置信息不完整");
            }

            // 构建数族发票请求参数
            String serviceId = "SCDXYZM";
            JSONObject content = new JSONObject();
            content.put("yzm", validCode); // 添加验证码参数

            // 构建整体请求体
            JSONObject body = new JSONObject();
            body.put("serviceId", serviceId);
            body.put("dlzh", dlzh);
            body.put("nsrsbh", sellerInfo.get("sellerTaxNumber"));
            body.put("content", content);

            // 调用数族发票API
            log.info("提交验证码请求参数: {}", body);
            String response = CommitValidCodeRequest(appId, appSecret, body.toString());
            log.info("数族发票API响应: {}", response);

            // 解析响应结果
            JSONObject jsonResponse = JSONUtil.parseObj(response);
            String code = jsonResponse.getStr("code");
            String msg = jsonResponse.getStr("msg");

            // 检查响应是否成功
            if ("0".equals(code)) {
                resultDto.setSuccess(true);
                resultDto.setCode(InvoiceErrorCodeEnum.GET_VALID_CODE_SUCCESS.getCode());
                resultDto.setDescription(msg);
                log.info("发送验证码成功，商户ID: {}", sellerId);
            } else {
                String message = jsonResponse.getStr("msg", "获取验证码失败");
                resultDto.setSuccess(false);
                resultDto.setCode(Integer.parseInt(code));
                resultDto.setDescription(message);
                log.error("获取验证码失败: {}", message);
            }
        } catch (Exception e) {
            resultDto.setSuccess(false);
            resultDto.setDescription("获取验证码失败，请稍后重试");
            log.error("获取验证码时发生异常", e);
            throw new InvoiceException("获取验证码失败，请稍后重试");
        }
        return resultDto;
    }


    //-----------参数构建----------
    private JSONObject buildInvoiceRequestBody(InvoiceRequestDtoOfShuZu invoiceRequestDtoOfShuZu, String fpqqlsh, String dlzh) {

        String serviceId = "FPKJ"; // 服务ID，FPKJ表示发票开具
        String nsrsbh = invoiceRequestDtoOfShuZu.getXfsh(); // 纳税人识别号

        JSONObject content = new JSONObject();
        // 基础参数
        content.put("sync", true); // 是否同步请求，true表示同步
        content.put("fpqqlsh", fpqqlsh); // 发票请求流水号，用于唯一标识请求
        content.put("hsbz", invoiceRequestDtoOfShuZu.getHsbz()); // 含税标志，0:不含税，1:含税
        content.put("fplxdm", invoiceRequestDtoOfShuZu.getFplxdm()); // 发票类型代码
        content.put("tdyslxdm", invoiceRequestDtoOfShuZu.getTdyslxdm()); // 特定要素类型代码

        // 备注信息（非空时添加）
        if (invoiceRequestDtoOfShuZu.getBz() != null && !invoiceRequestDtoOfShuZu.getBz().trim().isEmpty()) {
            content.put("bz", invoiceRequestDtoOfShuZu.getBz()); // 发票备注信息
        }

        // 销方信息
        content.put("xfmc", invoiceRequestDtoOfShuZu.getXfmc()); // 销方单位名称
        content.put("nsrsbh", nsrsbh); // 纳税人识别号（销方税号）
        if (invoiceRequestDtoOfShuZu.getXfdz() != null && !invoiceRequestDtoOfShuZu.getXfdz().trim().isEmpty()) {
            content.put("xfdz", invoiceRequestDtoOfShuZu.getXfdz()); // 销方地址
        }
        if (invoiceRequestDtoOfShuZu.getXflxdh() != null && !invoiceRequestDtoOfShuZu.getXflxdh().trim().isEmpty()) {
            content.put("xflxdh", invoiceRequestDtoOfShuZu.getXflxdh()); // 销方联系电话
        }
        if (invoiceRequestDtoOfShuZu.getXfkhh() != null && !invoiceRequestDtoOfShuZu.getXfkhh().trim().isEmpty()) {
            content.put("xfkhh", invoiceRequestDtoOfShuZu.getXfkhh()); // 销方开户银行
        }
        if (invoiceRequestDtoOfShuZu.getXfyhzh() != null && !invoiceRequestDtoOfShuZu.getXfyhzh().trim().isEmpty()) {
            content.put("xfyhzh", invoiceRequestDtoOfShuZu.getXfyhzh()); // 销方银行账号
        }

        // 购方信息
        content.put("gfmc", invoiceRequestDtoOfShuZu.getGfmc()); // 购方单位名称
        if (invoiceRequestDtoOfShuZu.getGfsh() != null && !invoiceRequestDtoOfShuZu.getGfsh().trim().isEmpty()) {
            content.put("gfsh", invoiceRequestDtoOfShuZu.getGfsh()); // 购方税号
        }
        if (invoiceRequestDtoOfShuZu.getGfdz() != null && !invoiceRequestDtoOfShuZu.getGfdz().trim().isEmpty()) {
            content.put("gfdz", invoiceRequestDtoOfShuZu.getGfdz()); // 购方地址
        }
        if (invoiceRequestDtoOfShuZu.getGflxdh() != null && !invoiceRequestDtoOfShuZu.getGflxdh().trim().isEmpty()) {
            content.put("gflxdh", invoiceRequestDtoOfShuZu.getGflxdh()); // 购方联系电话
        }
        if (invoiceRequestDtoOfShuZu.getGfyhzh() != null && !invoiceRequestDtoOfShuZu.getGfyhzh().trim().isEmpty()) {
            content.put("gfyhzh", invoiceRequestDtoOfShuZu.getGfyhzh()); // 购方银行账号
        }

        // 扩展参数设置（联系方式等）
        JSONObject spExt = new JSONObject();
        if (invoiceRequestDtoOfShuZu.getYxdz() != null && !invoiceRequestDtoOfShuZu.getYxdz().trim().isEmpty()) {
            spExt.put("yxdz", invoiceRequestDtoOfShuZu.getYxdz()); // 邮箱地址
        }
        if (invoiceRequestDtoOfShuZu.getSjhm() != null && !invoiceRequestDtoOfShuZu.getSjhm().trim().isEmpty()) {
            spExt.put("sjhm", invoiceRequestDtoOfShuZu.getSjhm()); // 手机号码
        }

        if (!spExt.isEmpty()) {
            content.put("spExt", spExt);
        }

        // 不动产经营租赁服务参数处理
        if (invoiceRequestDtoOfShuZu.getBdcjyzlfw() != null) {
            InvoiceRequestDtoOfShuZu.bdcjyzlfw bdcjyzlfw = invoiceRequestDtoOfShuZu.getBdcjyzlfw();
            JSONArray bdcjyzzfwArray = new JSONArray();
            JSONObject bdcjyzzfwObj = new JSONObject();
            bdcjyzzfwObj.put("fwcqzshm", bdcjyzlfw.getFwcqzshm() != null ? bdcjyzlfw.getFwcqzshm() : ""); // 房屋产权证书号码
            bdcjyzzfwObj.put("bdcdz", bdcjyzlfw.getBdcdz()); // 不动产地址
            bdcjyzzfwObj.put("zlqq", bdcjyzlfw.getZlqq()); // 租赁起期
            bdcjyzzfwObj.put("zlqz", bdcjyzlfw.getZlqz()); // 租赁止期
            bdcjyzzfwObj.put("kdsbz", bdcjyzlfw.getKdsbz()); //  knockdown标志
            bdcjyzzfwObj.put("mjdw", bdcjyzlfw.getMjdw()); // 面积单位
            bdcjyzzfwArray.add(bdcjyzzfwObj);
            content.put("bdcjyzlfw", bdcjyzzfwArray); // 不动产经营租赁服务信息数组
        }

        // 添加商品明细
        JSONArray mxListArray = new JSONArray();
        if (invoiceRequestDtoOfShuZu.getMxListList() != null && !invoiceRequestDtoOfShuZu.getMxListList().isEmpty()) {
            for (InvoiceRequestDtoOfShuZu.mxList mxList : invoiceRequestDtoOfShuZu.getMxListList()) {
                JSONObject mxListItem = new JSONObject();
                mxListItem.put("fphxz", "0"); // 发票行性质，0表示正常行，1表示折扣行
                mxListItem.put("spmc", mxList.getSpmc()); // 商品名称
                mxListItem.put("spbm", mxList.getSpbm() != null ? mxList.getSpbm() : "4050101000000000000"); // 商品编码
                mxListItem.put("dj", mxList.getJe()); // 单价
                mxListItem.put("spsl", "1"); // 商品数量
                mxListItem.put("je", mxList.getJe()); // 金额
                mxListItem.put("sl", mxList.getSl()); // 税率
                mxListItem.put("se", mxList.getSe()); // 税额

                if (mxList.getYhzcbs() != null && !mxList.getYhzcbs().trim().isEmpty()) {
                    mxListItem.put("yhzcbs", mxList.getYhzcbs()); // 优惠政策标识
                }
                if (mxList.getLslbs() != null && !mxList.getLslbs().trim().isEmpty()) {
                    mxListItem.put("lslbs", mxList.getLslbs()); // 零税率标识
                }
                if (mxList.getZzstsgl() != null && !mxList.getZzstsgl().trim().isEmpty()) {
                    mxListItem.put("zzstsgl", mxList.getZzstsgl()); // 增值税特殊管理
                }

                mxListArray.add(mxListItem);
            }
        }
        content.put("mxList", mxListArray); // 商品明细列表

        // 构建整体请求体
        JSONObject body = new JSONObject();
        body.put("serviceId", serviceId); // 服务ID
        body.put("dlzh", dlzh); // 登录账号
        body.put("nsrsbh", nsrsbh); // 纳税人识别号
        body.put("content", content); // 内容对象

        return body;
    }

    private JSONObject buildRedInvoiceRequestBody(RedInvoiceRequestDtoOfShuZu redInvoiceRequestDtoOfShuZu, String dlzh) {
        String serviceId = "HZXXBSC";
        String nsrsbh = redInvoiceRequestDtoOfShuZu.getXfsh();

        JSONObject content = new JSONObject();
        content.put("yfphm", redInvoiceRequestDtoOfShuZu.getYfphm()); // 原发票号码
        content.put("chyydm", redInvoiceRequestDtoOfShuZu.getChyydm()); // 冲红原因代码
        content.put("hzcxje", redInvoiceRequestDtoOfShuZu.getHzcxje()); // 开票金额(不含税)
        content.put("hzcxse", redInvoiceRequestDtoOfShuZu.getHzcxse()); // 开票税额
        content.put("sqly", redInvoiceRequestDtoOfShuZu.getSqly()); // 申请来源
        content.put("xfsh", redInvoiceRequestDtoOfShuZu.getXfsh()); //
        content.put("yfplxdm", redInvoiceRequestDtoOfShuZu.getYfplxdm()); //
        content.put("ykprq", redInvoiceRequestDtoOfShuZu.getYkprq()); //
        content.put("tdyslxdm", redInvoiceRequestDtoOfShuZu.getTdyslxdm()); // 特定要素类型代码

        // 添加冲红金额字段
        if (redInvoiceRequestDtoOfShuZu.getJe() != null && !redInvoiceRequestDtoOfShuZu.getJe().isEmpty()) {
            content.put("je", redInvoiceRequestDtoOfShuZu.getJe()); // 冲红金额
        }
        if (redInvoiceRequestDtoOfShuZu.getSe() != null && !redInvoiceRequestDtoOfShuZu.getSe().isEmpty()) {
            content.put("se", redInvoiceRequestDtoOfShuZu.getSe()); // 冲红税额
        }
        if (redInvoiceRequestDtoOfShuZu.getSl() != null && !redInvoiceRequestDtoOfShuZu.getSl().isEmpty()) {
            content.put("sl", redInvoiceRequestDtoOfShuZu.getSl()); // 冲红税率
        }

        JSONObject body = new JSONObject();
        body.put("serviceId", serviceId);
        body.put("dlzh", dlzh);
        body.put("nsrsbh", nsrsbh);
        body.put("content", content);

        return body;
    }

    private JSONObject buildQueryInvoiceStatusBody(String fpqqlsh, String dlzh, String nsrsbh) {

        String serviceId = "FPCX";

        JSONObject content = new JSONObject();
        content.put("fpqqlsh", fpqqlsh);

        JSONObject body = new JSONObject();
        body.put("serviceId", serviceId);
        body.put("dlzh", dlzh);
        body.put("nsrsbh", nsrsbh);
        body.put("content", content);

        return body;
    }

    /**
     * 构建红票查询请求参数
     */
    private JSONObject buildQueryRedInvoiceStatusBody(String redInvoiceConfirmId, String dlzh, String nsrsbh) {
        // 红票查询的serviceId可能不同，这里假设是"HZFPCX"，需要根据实际API调整
        String serviceId = "HZFPCX";

        JSONObject content = new JSONObject();
        content.put("hzfpxxqrdid", redInvoiceConfirmId); // 红票信息确认单ID
        content.put("xfsh", nsrsbh); // 销方税号

        JSONObject body = new JSONObject();
        body.put("serviceId", serviceId);
        body.put("dlzh", dlzh);
        body.put("nsrsbh", nsrsbh);
        body.put("content", content);

        return body;
    }

    /**
     * 发送红票状态查询请求
     */
    private String queryRedInvoiceStatusRequest(String appId, String appSecret, String body) {
        log.info("数族红票状态查询请求的body: {}", body);
        Date dNow = new Date();
        long timestamp = dNow.getTime();
        log.info("当前时间戳：{}", timestamp);
        String date = String.valueOf(timestamp);
        String accessToken = getToken(appId, appSecret);
        log.info("获取的token: {}", accessToken);

        // 计算签名
        String sign = Base64.getEncoder().encodeToString(DigestUtil.md5Hex(body + date + accessToken).getBytes());

        Map<String, String> headers = new HashMap<>();
        headers.put("AppId", appId);
        headers.put("Date", date);
        headers.put("Content-MD5", sign);
        headers.put("Content-Type", "application/json");

        // 使用正确的红票查询API地址，这里假设是这个地址，需要根据实际API调整
        return HttpUtil.httpRequest(URL + "/invoiceEx/zpy/electric/invoice/redIssued", body, headers);
    }

    private JSONObject buildRedeliverRequestBody(InvoiceRedeliverRequestDto redeliverRequestDto, String dlzh) {
        String serviceId = "reSendMessage";
        String nsrsbh = redeliverRequestDto.getSellerTaxNumber();

        // 构建content对象
        JSONObject content = new JSONObject();

        // 只有当email不为null且不为空串时才添加
        if (!ObjectUtil.isEmpty(redeliverRequestDto.getEmail())) {
            content.put("email", redeliverRequestDto.getEmail());
        }

        // 只有当telNum不为null且不为空串时才添加
//        if (!ObjectUtil.isEmpty(redeliverRequestDto.getPhoneNumber())) {
//            content.put("telNum", redeliverRequestDto.getPhoneNumber());
//        }

        if (!ObjectUtil.isEmpty(redeliverRequestDto.getInvoiceNo())) {
            content.put("fphm", redeliverRequestDto.getInvoiceNo());
        }else {
            log.error("重新交付时发票号码为空,数据错误,请联系管理人员");
            throw new InvoiceException("重新交付时发票号码为空,数据错误,请联系管理人员");
        }

        // 构建整体请求体
        JSONObject body = new JSONObject();
        body.put("serviceId", serviceId);
        body.put("dlzh", dlzh);
        body.put("nsrsbh", nsrsbh);
        body.put("content", content);

        return body;
    }


    //----------数族http请求--------

    /**
     * 获取accessToken
     */
    private String getToken(String appId, String appSecret) {
        String parm = "appId=" + appId + "&appScrt=" + appSecret;

        log.info("获取数族token参数: {}", parm);
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");

        String response = HttpUtil.httpRequest(path, parm, headers);
        log.info("获取数族token响应: {}", response);

        JSONObject json = JSONUtil.parseObj(response);
        String accessToken = json.getJSONObject("result").getStr("accessToken");
        log.info("获取数族token成功: {}", accessToken);

        return accessToken;
    }

    /**
     * 发送发票请求
     */
    private String invoiceRequest(String appId, String appSecret, String body) {
        log.info("数族发票请求的body: {}", body);
        Date dNow = new Date();
        long timestamp = dNow.getTime();
        log.info("当前时间戳：{}", timestamp);
        String date = String.valueOf(timestamp);
        String accessToken = getToken(appId, appSecret);
        log.info("获取的token: {}", accessToken);

        // 计算签名
        String sign = Base64.getEncoder().encodeToString(DigestUtil.md5Hex(body + date + accessToken).getBytes());

        Map<String, String> headers = new HashMap<>();
        headers.put("AppId", appId);
        headers.put("Date", date);
        headers.put("Content-MD5", sign);
        headers.put("Content-Type", "application/json");

        return HttpUtil.httpRequest(URL + "/invoiceEx/zpy/electric/invoice/issued", body, headers);
    }

    /**
     * 发送发票查询请求
     */
    private String queryInvoiceRequest(String appId, String appSecret, String body) {
        log.info("数族发票查询请求的body: {}", body);
        Date dNow = new Date();
        long timestamp = dNow.getTime();
        log.info("当前时间戳：{}", timestamp);
        String date = String.valueOf(timestamp);
        String accessToken = getToken(appId, appSecret);
        log.info("获取的token: {}", accessToken);

        // 计算签名
        String sign = Base64.getEncoder().encodeToString(DigestUtil.md5Hex(body + date + accessToken).getBytes());

        Map<String, String> headers = new HashMap<>();
        headers.put("AppId", appId);
        headers.put("Date", date);
        headers.put("Content-MD5", sign);
        headers.put("Content-Type", "application/json");

        // 使用正确的API地址
        return HttpUtil.httpRequest(URL + "/invoiceEx/zpy/electric/invoice/query", body, headers);
    }

    /**
     * 发送发票请求
     */
    private String redeliverRequest(String appId, String appSecret, String body) {
        log.info("数族发票请求的body: {}", body);
        Date dNow = new Date();
        long timestamp = dNow.getTime();
        log.info("当前时间戳：{}", timestamp);
        String date = String.valueOf(timestamp);
        String accessToken = getToken(appId, appSecret);
        log.info("获取的token: {}", accessToken);

        // 计算签名
        String sign = Base64.getEncoder().encodeToString(DigestUtil.md5Hex(body + date + accessToken).getBytes());

        Map<String, String> headers = new HashMap<>();
        headers.put("AppId", appId);
        headers.put("Date", date);
        headers.put("Content-MD5", sign);
        headers.put("Content-Type", "application/json");

        return HttpUtil.httpRequest(URL + "/invoiceEx/zpy/electric/invoice/reSend", body, headers);
    }

    /**
     * 发送红票请求
     */
    private String redInvoiceRequest(String appId, String appSecret, String body) {
        log.info("数族红票请求的body: {}", body);
        Date dNow = new Date();
        long timestamp = dNow.getTime();
        log.info("当前时间戳：{}", timestamp);
        String date = String.valueOf(timestamp);
        String accessToken = getToken(appId, appSecret);
        log.info("获取的token: {}", accessToken);

        // 计算签名
        String sign = Base64.getEncoder().encodeToString(DigestUtil.md5Hex(body + date + accessToken).getBytes());

        Map<String, String> headers = new HashMap<>();
        headers.put("AppId", appId);
        headers.put("Date", date);
        headers.put("Content-MD5", sign);
        headers.put("Content-Type", "application/json");

        // 使用正确的红票API地址，这里假设是这个地址，实际使用时需要替换为正确的API地址
        return HttpUtil.httpRequest(URL + "/invoiceEx/zpy/electric/invoice/applyRedInformation", body, headers);
    }

    /**
     * 获取验证码请求
     */
    private String getValidCodeRequest(String appId, String appSecret, String body) {
        log.info("数族获取验证码请求的body: {}", body);
        Date dNow = new Date();
        long timestamp = dNow.getTime();
        log.info("当前时间戳：{}", timestamp);
        String date = String.valueOf(timestamp);
        String accessToken = getToken(appId, appSecret);
        log.info("获取的token: {}", accessToken);

        // 计算签名
        String sign = Base64.getEncoder().encodeToString(DigestUtil.md5Hex(body + date + accessToken).getBytes());

        Map<String, String> headers = new HashMap<>();
        headers.put("AppId", appId);
        headers.put("Date", date);
        headers.put("Content-MD5", sign);
        headers.put("Content-Type", "application/json");

        // 使用正确的红票API地址，这里假设是这个地址，实际使用时需要替换为正确的API地址
        return HttpUtil.httpRequest(URL + "/invoiceEx/zpy/electric/auth/validateLogon", body, headers);
    }

    /**
     * 提交验证码请求
     */
    private String CommitValidCodeRequest(String appId, String appSecret, String body) {
        log.info("数族提交验证码请求的body: {}", body);
        Date dNow = new Date();
        long timestamp = dNow.getTime();
        log.info("当前时间戳：{}", timestamp);
        String date = String.valueOf(timestamp);
        String accessToken = getToken(appId, appSecret);
        log.info("获取的token: {}", accessToken);

        // 计算签名
        String sign = Base64.getEncoder().encodeToString(DigestUtil.md5Hex(body + date + accessToken).getBytes());

        Map<String, String> headers = new HashMap<>();
        headers.put("AppId", appId);
        headers.put("Date", date);
        headers.put("Content-MD5", sign);
        headers.put("Content-Type", "application/json");

        // 使用正确的红票API地址，这里假设是这个地址，实际使用时需要替换为正确的API地址
        return HttpUtil.httpRequest(URL + "/invoiceEx/zpy/electric/auth/uploadVerificationCode", body, headers);
    }


    //--------------------------------


    /**
     * 生成随机发票请求流水号
     */
    private String randomFpqqlsh() {
        StringBuilder sb = new StringBuilder("isvkp");
        for (int i = 0; i < RANDOM_STRING_LENGTH; i++) {
            int index = (int) (RANDOM.nextFloat() * ALLOWED_CHARS.length());
            char randomChar = ALLOWED_CHARS.charAt(index);
            sb.append(randomChar);
        }
        System.out.println("发票交易流水号为:" + sb.toString());
        return sb.toString();
    }


}
